<?php

class SiteDataFinder
{
  protected $_elements = array(
    'indexedPages', 'blogsMentions', 'newVisits', 'pageViews', 'entrances', 'pageRank',
    'inboundLinks', 'AdSenseIncome'
    );
  protected $_pageRank;
  protected $_pdo;
  protected $_elementsAmount;
    
  public function __construct()
  {   
    $this->_pdo = PDOFactory::getInstance();
    $this->_pageRank = new GooglePR();
    $this->_elementsAmount = count($this->_elements);
  }
  
  public function findNotExisted()
  { 
    $query = $this->_pdo->query(
      'SELECT `sites`.* FROM `sites` WHERE `sites`.`idSite` NOT IN ('.
      ' SELECT `sites_data`.`idSite` FROM `sites_data` GROUP BY `sites_data`.`idSite`'.
      ' )'
      );
    $query->setFetchMode(PDO::FETCH_ASSOC);
    $query->execute();    
    $count = 0;
    foreach( $query as $site ) {
      echo $site['idSite']."\n";
      $this->_createData($site);
      $count++;
    }
    return $count;
  }
  
  public function findOutdated()
  {   
    $timeLastUpdate = 60 * 60 * 24;
    $query = $this->_pdo->query(
      'SELECT `sites`.*'.
      'FROM `sites` '.
      'LEFT JOIN `sites_data` ON `sites`.`idSite` = `sites_data`.`idSite` AND `sites_data`.`lastUpdated` >= DATE_FORMAT(NOW(), "%Y-%m-%d 00:00:00")'.
      'WHERE '.
      ' `sites_data`.`idSitesData` IS NULL'
      );
    $query->setFetchMode(PDO::FETCH_ASSOC);
    $query->execute();    
    $count = 0;
    foreach( $query as $site ) {
      echo $site['idSite']."\n";
      $this->_createData($site);
      $count++;
    }    
    return $count;
  }
  
  public function findNotCompleted()
  {   
    $query = $this->_pdo->query(
      'SELECT `sites_data`.*, `sites`.*'.
      'FROM `sites` '.
      'INNER JOIN `sites_data` ON `sites`.`idSite` = `sites_data`.`idSite` '.
      'WHERE '.
      ' `sites_data`.`dataStatus` = "new" '
      );
    $query->setFetchMode(PDO::FETCH_ASSOC);
    $query->execute();    
    $count = 0;
    foreach( $query as $site ) {
      echo $site['idSite']."\n";
      $this->_createData($site);
      $count++;
    }       
    return $count;
  }
  
  public function findFailed()
  {   
    $query = $this->_pdo->query(
      'SELECT `sites_data`.*, `sites`.*'.
      'FROM `sites` '.
      'INNER JOIN `sites_data` ON `sites`.`idSite` = `sites_data`.`idSite` '.
      'WHERE '.
      ' `sites_data`.`dataStatus` = "error" '
      );
    $query->setFetchMode(PDO::FETCH_ASSOC);
    $query->execute();      
    $count = 0;
    foreach( $query as $site ) {
      echo $site['idSite']."\n";
      $this->_createData($site);      
      $count++;
    }       
    return $count;
  }  
  
  protected function _createData( $site )
  {
    $elementsSaved = 0;
    $elementsToSave = $this->_elementsAmount; // Because not everything we look for - Yoda
    
    // clearing some objects
    $info = null;
    $gaHelper = null;
    $blogInfo = null;
    $ga = $site['gaId'] && $site['gaLogin'] && $site['gaPassword']; // is set Google Analytics?
    if( !$ga ) {
      $elementsToSave -= 3; // Minus 3 elements because of lack of Google Analytics
    }  
    $as = $site['asLogin'] && $site['asPassword']; // is set Google AdSense?
    if( !$as ) {
      $elementsToSave -= 1;
    }
      
    // Iterating through elements to set
    $complete = false;
    foreach( $this->_elements as $element ) {
      $value = isset($site[$element]) ? $site[$element] : null;    
      $set = array();
      if( $value === null ) {
        try {        
          if( $ga ) {        
            switch($element) {
              case 'newVisits':
                $gaHelper = $gaHelper ? $gaHelper : new Helper_GoogleAnalytics($site['gaLogin'],$site['gaPassword']);
                $value = $gaHelper->getNewVisits($site['gaId']);
                break;
              case 'pageViews':
                $gaHelper = $gaHelper ? $gaHelper : new Helper_GoogleAnalytics($site['gaLogin'],$site['gaPassword']);
                $value = $gaHelper->getPageviews($site['gaId']);
                break;
              case 'entrances':
                $gaHelper = $gaHelper ? $gaHelper : new Helper_GoogleAnalytics($site['gaLogin'],$site['gaPassword']);
                $value = $gaHelper->getEntrances($site['gaId']);
                break;
            }         
          }
          if( $as ) {
            switch($element) {
              case 'AdSenseIncome':
                require_once './functions/AdSense.php';
                $value = getAdSenseReport($site['asLogin'],$site['asPassword']);
                if( !is_numeric($value) ) {
                  throw new Exception('Problem with retrieving todays income from AdSense');
                }
                break;
            }          
          }
          switch($element) {
            case 'indexedPages':
              $info = $info ? $info : new GoogleSiteInfo($site['hostname']);
              $value = $info->getIndexedPagesAmount();
              break;
            case 'blogsMentions':
              $blogInfo = new SocialMediaInfo($site['name']);
              $value = $blogInfo->getBlogsMentionsAmount();          
              break;
            case 'pageRank':          
              $value = $this->_pageRank->GetPR($site['hostname']);
              break;
            case 'inboundLinks':
              $info = $info ? $info : new GoogleSiteInfo($site['hostname']);
              $value = $info->getInboundLinksAmount();          
              break;
          } 
          if( $value !== null ) {
            $set = array(
              $element => $value,        
              );
            $elementsSaved += 1;
          }
        } catch( Exception $e ) {
          $set = array();
          $set['dataError'] = get_class($e).' '.$e->getMessage();
          $set['dataStatus'] = 'error';
        }
      } else {
        $elementsToSave -= 1;
      }
      if( $elementsSaved == $elementsToSave && !isset($set['dataStatus']) ) {
        $complete = true;
        $set['dataStatus'] = 'completed';      
      }
     
      // Saving record while value has been found or error/status change has occured
      if( $set ) {
        // Fucked up sql generator
        // (no time for creating universal class/funcion/component/library)
        if( isset($site['idSitesData']) ) {
          $sql = 'UPDATE `sites_data` SET ';
          foreach( array_keys($set) as $key ) {
            $sql .= ' `'.$key.'` = :'.$key.',';
          }
          $sql = rtrim($sql,',');
          $sql .= ' WHERE `sites_data`.`idSitesData` = '.(int)$site['idSitesData'];
          $state = $this->_pdo->prepare($sql);
          foreach( $set as $key => $v ) {
            if( is_string($v) ) {
              $state->bindValue(':'.$key,$v,PDO::PARAM_STR);
            } else {
              $state->bindValue(':'.$key,$v,PDO::PARAM_INT);
            }
          }
          $state->execute();
        } else {
          $set['idSite'] = $site['idSite'];
          $sql = 'INSERT INTO `sites_data` (';
          foreach( array_keys($set) as $key ) {
            $sql .= ' `'.$key.'`,';
          }
          $sql = rtrim($sql,',');
          $sql .= ') VALUES (';
          foreach( array_keys($set) as $key ) {
            $sql .= ' :'.$key.',';
          }
          $sql = rtrim($sql,',');
          $sql .= ')';
          $state = $this->_pdo->prepare($sql);
          foreach( $set as $key => $v ) {
            if( is_string($v) ) {
              $state->bindValue(':'.$key,$v,PDO::PARAM_STR);
            } else {
              $state->bindValue(':'.$key,$v,PDO::PARAM_INT);
            }
          }
          $state->execute();
          $site['idSitesData'] = $this->_pdo->lastInsertId();
        }
        //echo $site['hostname'].': '.$element.' = '.$value."\n";
        //print_r($set);
        //print_r($state->debugDumpParams())."\n\n";  
        
        if( $complete ) {
          break;
        }
      }  
    }      
  }
}